package cn.edu.ncu.housinghub.service.impl;

import cn.edu.ncu.housinghub.constant.ErrorCodeConstant;
import cn.edu.ncu.housinghub.constant.SystemConstant;
import cn.edu.ncu.housinghub.dto.request.checkout.CheckoutRequest;
import cn.edu.ncu.housinghub.dto.request.checkout.CheckoutHandleRequest;
import cn.edu.ncu.housinghub.entity.checkout.Checkout;
import cn.edu.ncu.housinghub.entity.checkout.CheckoutResult;
import cn.edu.ncu.housinghub.entity.user.User;
import cn.edu.ncu.housinghub.exception.BusinessException;
import cn.edu.ncu.housinghub.mapper.CheckoutMapper;
import cn.edu.ncu.housinghub.service.CheckoutService;
import cn.edu.ncu.housinghub.utils.common.TokenUtil;
import cn.edu.ncu.housinghub.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

/**
 * 退租服务实现类
 */
@Service
public class CheckoutServiceImpl implements CheckoutService {
    
    @Autowired
    private CheckoutMapper checkoutMapper;
    
    @Override
    public Result applyCheckout(CheckoutRequest request, String token) {
        try {
            // 获取当前用户信息
            User currentUser = TokenUtil.getUserByToken(token);
            if (currentUser == null) {
                throw new BusinessException(ErrorCodeConstant.TOKEN_INVALID);
            }
            
            // 验证用户是否有权限对该合同申请退租（需要是该合同的租客）
            boolean hasPermission = checkoutMapper.checkTenantPermission(currentUser.getId(), request.getContractId());
            if (!hasPermission) {
                throw new BusinessException(ErrorCodeConstant.USER_AUTH_ERROR);
            }

            // 检查是否已经有未处理的退租申请
            boolean hasExistingApplication = checkoutMapper.checkExistingApplication(currentUser.getId(), request.getContractId());
            if (hasExistingApplication) {
                throw new BusinessException(ErrorCodeConstant.APPLY_ALREADY, "该合同已有未处理的退租申请");
            }

            // 创建退租申请
            Checkout checkout = new Checkout();
            checkout.setUserId(currentUser.getId());
            checkout.setContractId(request.getContractId());
            checkout.setApplyDate(LocalDate.now());
            checkout.setCheckoutReason(request.getCheckoutReason());
            checkout.setCheckoutStatus(0); // 0=待审核
            checkout.setIsDeleted(false);
            
            // 插入退租申请
            int result = checkoutMapper.insertCheckout(checkout);
            if (result > 0) {
                return Result.success(checkout.getCheckoutId());
            } else {
                throw new BusinessException(ErrorCodeConstant.APPLY_ERROR);
            }
            
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCodeConstant.APPLY_ERROR, "退租申请提交失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result getTenantCheckoutList(String token) {
        try {
            User currentUser = TokenUtil.getUserByToken(token);
            if (currentUser == null) {
                throw new BusinessException(ErrorCodeConstant.TOKEN_INVALID);
            }
            
            List<Checkout> checkoutList = checkoutMapper.selectByTenantId(currentUser.getId());
            return Result.success(checkoutList);
            
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCodeConstant.USER_QUERY_ERROR, "获取退租申请列表失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result getLandlordCheckoutList(String token) {
        try {
            User currentUser = TokenUtil.getUserByToken(token);
            if (currentUser == null) {
                throw new BusinessException(ErrorCodeConstant.TOKEN_INVALID);
            }
            
            // 验证用户是否为房东
            if (!currentUser.getRole().equals(SystemConstant.ROLE_LANDLORD.getIntegerValue())) {
                throw new BusinessException(ErrorCodeConstant.USER_AUTH_ERROR);
            }
            
            List<Checkout> checkoutList = checkoutMapper.selectByLandlordId(currentUser.getId());
            return Result.success(checkoutList);
            
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCodeConstant.USER_QUERY_ERROR, "获取退租申请列表失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result handleCheckout(Long checkoutId, CheckoutHandleRequest request, String token) {
        try {
            User currentUser = TokenUtil.getUserByToken(token);
            if (currentUser == null) {
                throw new BusinessException(ErrorCodeConstant.TOKEN_INVALID);
            }
            
            // 验证用户是否为房东
            if (!currentUser.getRole().equals(SystemConstant.ROLE_LANDLORD.getIntegerValue())) {
                throw new BusinessException(ErrorCodeConstant.USER_AUTH_ERROR);
            }
            
            // 验证房东是否有权限处理该退租申请
            boolean hasPermission = checkoutMapper.checkLandlordPermission(currentUser.getId(), checkoutId);
            if (!hasPermission) {
                throw new BusinessException(ErrorCodeConstant.USER_AUTH_ERROR);
            }
            
            // 更新退租申请状态
            int status = request.getAgree() ? 1 : 2; // 1=已通过，2=已拒绝
            int result = checkoutMapper.updateCheckoutStatus(checkoutId, status);
            if (result <= 0) {
                throw new BusinessException(ErrorCodeConstant.APPLY_ERROR, "更新退租申请状态失败");
            }
            
            // 如果同意退租，创建退租结果记录
            if (request.getAgree()) {
                CheckoutResult checkoutResult = new CheckoutResult();
                Checkout checkout = new Checkout();
                checkout.setCheckoutId(checkoutId);
                checkoutResult.setCheckout(checkout);
                checkoutResult.setCheckoutDate(request.getActualCheckoutDate());
                checkoutResult.setPenaltyAmount(request.getPenaltyAmount());
                checkoutResult.setDepositDeductionAmount(request.getDepositDeductionAmount());
                
                checkoutMapper.insertCheckoutResult(checkoutResult);
            }
            
            return Result.success("退租申请处理成功");

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCodeConstant.APPLY_ERROR, "退租申请处理失败：" + e.getMessage());
        }
    }

    @Override
    public Result getCheckoutDetail(Long checkoutId, String token) {
        try {
            User currentUser = TokenUtil.getUserByToken(token);
            if (currentUser == null) {
                throw new BusinessException(ErrorCodeConstant.TOKEN_INVALID);
            }

            Checkout checkout = checkoutMapper.selectById(checkoutId);
            if (checkout == null) {
                throw new BusinessException(ErrorCodeConstant.USER_QUERY_ERROR, "退租申请不存在");
            }

            // 验证用户是否有权限查看该退租申请（租客或房东）
            boolean hasPermission = checkout.getUserId().equals(currentUser.getId()) ||
                                  checkoutMapper.checkLandlordPermission(currentUser.getId(), checkoutId);
            if (!hasPermission) {
                throw new BusinessException(ErrorCodeConstant.USER_AUTH_ERROR);
            }

            return Result.success(checkout);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCodeConstant.USER_QUERY_ERROR, "获取退租申请详情失败：" + e.getMessage());
        }
    }

    @Override
    public Result getTenantCheckoutResults(String token) {
        try {
            User currentUser = TokenUtil.getUserByToken(token);
            if (currentUser == null) {
                throw new BusinessException(ErrorCodeConstant.TOKEN_INVALID);
            }

            List<CheckoutResult> checkoutResults = checkoutMapper.selectCheckoutResultsByTenantId(currentUser.getId());
            return Result.success(checkoutResults);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCodeConstant.USER_QUERY_ERROR, "获取退租结果列表失败：" + e.getMessage());
        }
    }
}
